/*
 * Copyright 2009 BioTeam Inc
 * 
 * Licensed under License GNU LESSER GENERAL PUBLIC LICENSE version 3.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.gnu.org/copyleft/lesser.html
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package net.bioteam.appweb.submit;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

import org.apache.commons.io.FileUtils;

import junit.framework.TestCase;
import net.bioteam.appweb.Config;
import net.bioteam.appweb.TestConfig;
import net.bioteam.appweb.acd.AcdToProgram;
import net.bioteam.appweb.model.BeanshellProgramModifier;
import net.bioteam.appweb.model.Program;
import net.bioteam.appweb.model.ProgramBuilder;
import net.bioteam.appweb.model.XmlToProgram;
import net.bioteam.appweb.submit.CtrlException;
import net.bioteam.appweb.submit.DefaultCommandLineGenerator;
import net.bioteam.appweb.submit.ProgramValueBean;
import net.bioteam.common.utils.Utils;
import net.sf.ehcache.CacheManager;

public class DefaultCommandLineGeneratorTest extends TestCase {
	public DefaultCommandLineGeneratorTest(String name) {
		super(name);
	}

	public void setUp() throws Exception {
		TestConfig.init();
		 BeanshellProgramModifier modifier=new BeanshellProgramModifier();
         ProgramBuilder.modifiers.add(modifier);
	}


	protected void tearDown() throws Exception {
		TestConfig.shutdown();
	}

	public static void main(String args[]) {
		DefaultCommandLineGeneratorTest test = new DefaultCommandLineGeneratorTest(
				"testPfam_scan");
		junit.textui.TestRunner.run(test);
	}

	/**
	 * Test command line generator
	 * for boolean value
	 * undefined value
	 * precond evaluation.
	 * ctrl evaluation.
	 * @throws Exception
	 */
	public void testCommandGeneration1() throws Exception {
		ProgramBuilder.cache.remove("example");

		Program program = ProgramBuilder.getProgram("example");
		ProgramValueBean bean = new ProgramValueBean(program);

		// set value for parameter;
		bean.setValue("first", "value1"); // group1
		assertEquals(1, program.getParameter("first").getGroup().intValue());
		assertEquals(1, program.getParameter("first").getGroup().intValue());
		bean.setValue("second", "2"); // group -1
		assertEquals(-1, program.getParameter("second").getGroup().intValue());

		bean.setValue("seq", "seqfile"); // group 5
		assertEquals(5, program.getParameter("seq").getGroup().intValue());
		bean.setValue("str", "strvalue"); // group 4
		assertEquals(4, program.getParameter("str").getGroup().intValue());
		bean.setValue("aint", "6"); // group 5
		assertEquals(5, program.getParameter("aint").getGroup().intValue());
		bean.setValue("afloat", "6.2"); // group 5
		assertEquals(5, program.getParameter("afloat").getGroup().intValue());
		//boolean value is set 1 or 0
		bean.setValue("aswitch", "1"); // group 5
		assertEquals(5, program.getParameter("aswitch").getGroup().intValue());
		bean.setValue("bswitch", "1"); // group 5
		assertEquals(5, program.getParameter("bswitch").getGroup().intValue());
		bean.setValue("a_selection", "value1"); // group 10
		assertEquals(10, program.getParameter("a_selection").getGroup().intValue());
		bean.setValue("multi_selection", "\"valuex3 valuex2\""); // group 11
		assertEquals(11, program.getParameter("multi_selection").getGroup().intValue());
		bean.setValue("seq1", "seq1"); // group 5
		assertEquals(5, program.getParameter("seq1").getGroup().intValue());

		DefaultCommandLineGenerator generator = new DefaultCommandLineGenerator();
		
		String cmdline = generator.generateScript((ProgramValueBean) bean
				.myClone(), null);
		String expectedCmd = "-second 2 test1 -first value1  -str strvalue  -seq seqfile  -int 6  -float 6.2  -aswitch  -seq1 seq1  -excl value1  -list \"valuex3 valuex2\"";
		
		assertEquals(expectedCmd, cmdline.trim());

		
		bean = new ProgramValueBean(program);

		// set value for parameter;
		bean.setValue("first", "value1"); // group1
		bean.setValue("second", "2"); // group -1

		//Here the seq is undefine. Test whether out code can handle this properly or not.
		// bean.setValue("seq", "seqfile"); //undefined.
		
		//infile is precond on seq. test our code can handle this properly or not.
		bean.setValue("infile", "infile"); // precond on seq
		bean.setValue("str", "strvalue"); // group 4
		bean.setValue("aint", "6"); // group 5
		bean.setValue("afloat", "6.2"); // group 5
		bean.setValue("aswitch", "1"); // group 5
		bean.setValue("bswitch", "1"); // group 5
		bean.setValue("a_selection", "value1"); // group 10
		bean.setValue("multi_selection", "\"valuex3 valuex2\""); // group 11
		bean.setValue("seq1", "seq1"); // group 5

		cmdline = generator.generateScript((ProgramValueBean) bean.myClone(), null);
		expectedCmd = "-second 2 test1 -first value1  -str strvalue  -int 6  -float 6.2  -aswitch  -seq1 seq1  -excl value1  -list \"valuex3 valuex2\"";
		assertEquals(expectedCmd, cmdline.trim());

		// TODO test ctrl
		bean = new ProgramValueBean(program);
		bean.setValue("aint", "20"); // group 5

		try {
			cmdline = generator.generateScript((ProgramValueBean) bean.myClone(), null);
			fail("ctrl is not evaluated properly");
		} catch (CtrlException e) {
			// good.
		}
	}
	
	public void testParamFile() throws Exception {
		ProgramBuilder.cache.remove("phiblast");

		Program program = ProgramBuilder.getProgram("phiblast");
		ProgramValueBean bean = new ProgramValueBean(program);

		// set value for parameter;
		bean.setValue("pattern", "xxx");
		UnfinishedJob job=new UnfinishedJob();
		job.setWorkdir("");
		CommandGenerator generator=new DefaultCommandLineGenerator();
		String cmdline = generator.generateScript((ProgramValueBean) bean.myClone(), job);
		File file=new File("pattern.dat");
		assertTrue(file.exists());
		FileInputStream fin=new FileInputStream(file);
		String content=FileUtils.readFileToString(file);
		assertEquals(content, "ID  PATTERN\nPA  xxx\n//\n");
	}
	
	
	public void testMrBayes_mpi() throws Exception {
		ProgramBuilder.cache.remove("MrBayes-mpi");

		Program program = ProgramBuilder.getProgram("MrBayes-mpi");
		ProgramValueBean bean = new ProgramValueBean(program);

		// set value for parameter;
		bean.setValue("nexus_file", "file");
		
		
		UnfinishedJob job=new UnfinishedJob();
		job.setWorkdir("D:/workspace/appwebtest");;
		CommandGenerator generator=new DefaultCommandLineGenerator();
		if (bean.getValue(CommandSubmitter.GENERATOR)!=null)
		{
			generator=(CommandGenerator)Class.forName(bean.getValue(CommandSubmitter.GENERATOR)).newInstance();
		}
		String cmdline = generator.generateScript((ProgramValueBean) bean.myClone(), job);
		File file=new File("D:/workspace/appwebtest/mrbayes.txt");
		assertTrue(file.exists());
		//FileInputStream fin=new FileInputStream(file);
		String content=FileUtils.readFileToString(file);
		System.out.println(content);
	}
	
	public void testMerlinRegress() throws Exception {
		ProgramBuilder.cache.remove("merlin-regress");

		Program program = ProgramBuilder.getProgram("merlin-regress");
		ProgramValueBean bean = new ProgramValueBean(program);

		bean.setValue("pedfile", "inputs/asp.ped");
		bean.setValue("mapfile", "inputs/asp.map");
		bean.setValue("datafile", "inputs/asp.dat");
		bean.setValue("mean", "0.0");
		bean.setValue("variance", "1.5");
		bean.setValue("Heritability", "0.8");
		
		
		UnfinishedJob job=new UnfinishedJob();
		job.setWorkdir("D:/workspace/appwebtest");;
		CommandGenerator generator=new DefaultCommandLineGenerator();
		if (bean.getValue(CommandSubmitter.GENERATOR)!=null)
		{
			generator=(CommandGenerator)Class.forName(bean.getValue(CommandSubmitter.GENERATOR)).newInstance();
		}
		String cmdline = generator.generateScript((ProgramValueBean) bean.myClone(), job);
		System.out.println(cmdline);
	}
	
	public void testPfam_scan() throws Exception {
		ProgramBuilder.cache.remove("pfam_scan");

		Program program = ProgramBuilder.getProgram("pfam_scan");
		ProgramValueBean bean = new ProgramValueBean(program);

		bean.setValue("infile", "infile");
		bean.setValue("output", "out");
		bean.setValue("overlap", "1");
		
		
		UnfinishedJob job=new UnfinishedJob();
		job.setWorkdir("D:/workspace/appwebtest");;
		CommandGenerator generator=new DefaultCommandLineGenerator();
		String cmdline = generator.generateScript((ProgramValueBean) bean.myClone(), job);
		String expected="pfam_scan.pl $HMMERDB  --fast  -o $value --overlap  infile";
		assertEquals(expected, cmdline.trim());
	}
	
}
